#ifndef _PENTAX_API_H_
#define _PENTAX_API_H_
#include <windows.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>

using namespace std;

/////////////////////////////////////////////////////////////////////////////////////
template <class T>
class Singleton
{
	static T* _self;
	static int _refcount;
protected:
	Singleton(){}
	virtual ~Singleton(){_self=NULL;}
public:
	static T* Instance();
	void FreeInst();
};
template <class T>
T*  Singleton<T>::_self = NULL;

template <class T>
int  Singleton<T>::_refcount=0;


template <class T>
T*  Singleton<T>::Instance()
{
	try
	{
	if(!_self)
		_self=new T;
	_refcount++;
	}
	catch(...)
	{
	_self=NULL;
	}

	return _self;
}

template <class T>
void  Singleton<T>::FreeInst()
{
	if(--_refcount==0)
		delete this;
}
/////////////////////////////////////////////////////////////////////////////////////

class c_pentax_slr:public Singleton<c_pentax_slr>
{
public:
/////////////////////////// Enum //////////////////////////////////////////////
	enum model_e
	{
		PSLR_ID1_K20D    = 0x12cd2,
		PSLR_ID2_K20D    = 0x1ba,
		PSLR_ID1_K10D    = 0x12c1e,
		PSLR_ID2_K10D    = 0x1a5,
		PSLR_ID1_K110D   = 0x12b9d,
		PSLR_ID2_K110D   = 0x1ac,
		PSLR_ID1_K100D   = 0x12b9c,
		PSLR_ID2_K100D   = 0x189,
		PSLR_ID1_IST_D   = 0x12994,
		PSLR_ID2_IST_D   = 0x141,
		PSLR_ID1_IST_DS  = 0x12aa2,
		PSLR_ID2_IST_DS  = 0x177,
		PSLR_ID1_IST_DS2 = 0x12b60,
		PSLR_ID2_IST_DS2 = 0x19a,
		PSLR_ID1_IST_DL  = 0x12b1a,
		PSLR_ID2_IST_DL  = 0x188,
		PSLR_ID1_GX10    = 0x12c20,
		PSLR_ID2_GX10    = 0x1ad,
		PSLR_ID1_GX20    = 0x12cd4,
		PSLR_ID2_GX20    = 0x1c6
	};
	typedef enum {
		PSLR_EXPOSURE_MODE_GREEN,
		PSLR_EXPOSURE_MODE_P,
		PSLR_EXPOSURE_MODE_SV,
		PSLR_EXPOSURE_MODE_TV,
		PSLR_EXPOSURE_MODE_AV,
		PSLR_EXPOSURE_MODE_TAV,
		PSLR_EXPOSURE_MODE_M,
		PSLR_EXPOSURE_MODE_B,
		PSLR_EXPOSURE_MODE_X,
		PSLR_EXPOSURE_MODE_MAX
	}exposure_mode_t;

////////////////////////// Structure //////////////////////////////////////////
	struct date_time_t 
	{
		int year, month, day, hour, min, sec;
		std::string to_str();
	};

	typedef unsigned char		uint8_t;
	typedef unsigned short int	uint16_t;
	typedef unsigned int		uint32_t;
	typedef int			        int32_t;

	struct pslr_status_brief{
		uint16_t power;
	} ;

	typedef struct {
		int32_t nom;
		int32_t denom;
	} pslr_rational_t;

	struct status_t{
		pslr_status_brief brief;
		uint16_t bufmask;                      /* 0x16 */
		uint32_t current_iso;                  /* 0x11c */
		pslr_rational_t current_shutter_speed; /* 0xf4 */
		pslr_rational_t current_aperture;      /* 0xfc */
		pslr_rational_t lens_max_aperture;     /* 0x12c */
		pslr_rational_t lens_min_aperture;     /* 0x134 */
		pslr_rational_t current_zoom;          /* 0x16c */
		pslr_rational_t set_shutter_speed;     /* 0x2c */
		pslr_rational_t set_aperture;          /* 0x34 */
		uint32_t set_iso;                      /* 0x60 */
		uint32_t jpeg_resolution;              /* 0x7c */
		uint32_t jpeg_saturation;              /* 0x8c */
		uint32_t jpeg_quality;                 /* 0x80 */
		uint32_t jpeg_contrast;                /* 0x94 */
		uint32_t jpeg_sharpness;               /* 0x90 */
		uint32_t jpeg_image_mode;              /* 0x88 */
		pslr_rational_t zoom;                  /* 0x16c */
		uint32_t focus;                        /* 0x174 */
		uint32_t image_format;                 /* 0x78 */
		uint32_t raw_format;                   /* 0x84 */
		uint32_t light_meter_flags;            /* 0x124 */
		pslr_rational_t ec;                    /* 0x3c */
		uint32_t custom_ev_steps;              /* 0x9c */
		uint32_t custom_sensitivity_steps;     /* 0xa0 */
		uint32_t exposure_mode;                /* 0xe0 */
		uint32_t user_mode_flag;               /* 0x1c */
		uint32_t af_point_select;              /* 0xbc */
		uint32_t selected_af_point;            /* 0xc0 */
		uint32_t focused_af_point;             /* 0x150 */
	};

#include "pentaxapi_decl.h"

public:

	std::string cpu_fw_ver();
	std::string dsp_fw_ver();

	int fileno();
	void fileno(int fn);

	float buttery_level();

	date_time_t date_time();
	void date_time(date_time_t dt);

	std::string model();

	void status_full();

	bool iso(uint32_t iso_v);

	bool exposure_mode(exposure_mode_t em_v);
	uint32_t release_count();

protected:
	friend class Singleton<c_pentax_slr>;

	c_pentax_slr();
	virtual ~c_pentax_slr();
	void load_functions();
	HMODULE h_module;

	uint32_t get_uint32(uint8_t *buf);
};

#endif
